package cn.windy.samary.utils;

import cn.windy.samary.core.annotation.OpLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class InterceptUtil {
    public static Object getMethodArg(ProceedingJoinPoint proceedingJoinPoint,
                                      int index) throws IllegalArgumentException, SecurityException,
            IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        Object[] args = proceedingJoinPoint.getArgs();
        return args[index - 1];
    }

    public static void setMethodArg(ProceedingJoinPoint proceedingJoinPoint,
                                    int index, Object value) throws IllegalArgumentException,
            SecurityException, IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        Object[] args = proceedingJoinPoint.getArgs();
        args[index - 1] = value;
    }

    public static Object getActionField(
            ProceedingJoinPoint proceedingJoinPoint, String fieldName)
            throws IllegalArgumentException, SecurityException,
            IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        return proceedingJoinPoint.getTarget().getClass()
                .getMethod(StringUtil.queryGetMethodString(fieldName))
                .invoke(proceedingJoinPoint.getTarget());
    }

    public static void setActionField(ProceedingJoinPoint proceedingJoinPoint,
                                      String fieldName, Object... value) throws IllegalArgumentException,
            SecurityException, IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        proceedingJoinPoint.getTarget().getClass().getMethod(
                StringUtil.querySetMethodString(fieldName),
                proceedingJoinPoint.getTarget().getClass()
                        .getMethod(StringUtil.queryGetMethodString(fieldName))
                        .getReturnType())
                .invoke(proceedingJoinPoint.getTarget(), value);
    }

    public static String getCurrentUserName(
            ProceedingJoinPoint proceedingJoinPoint)
            throws IllegalArgumentException, SecurityException,
            IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        String userName = "";
        try {
            userName = (String) proceedingJoinPoint.getTarget().getClass()
                    .getMethod("getCurrentUserName")
                    .invoke(proceedingJoinPoint.getTarget());
        } catch (Exception ex) {
        }
        return userName;
    }

    public static String getOperaterDesc(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature signature = (MethodSignature) proceedingJoinPoint
                .getSignature();
        Method method = signature.getMethod();
        // Class<?> clazz = proceedingJoinPoint.getTarget().getClass();
        Object[] args = proceedingJoinPoint.getArgs();
        OpLog annotation = (OpLog) method
                .getAnnotation(OpLog.class);
        if (!ObjectUtils.isEmpty(annotation)) {
            String operaterDesc = annotation.value();
            int[] operateVars = annotation.operateVars();
            for (int var : operateVars) {
                if (!StringUtils.isEmpty(var)) {
                    Object value = args[var - 1];
                    if (!ObjectUtils.isEmpty(value)) {
                        operaterDesc = operaterDesc.replaceFirst("\\$",
                                value.toString());
                    }
                }
            }
            return operaterDesc;
        }
        return "";
    }

    public static HttpServletRequest getRequest(
            ProceedingJoinPoint proceedingJoinPoint) {
        Object[] args = proceedingJoinPoint.getArgs();
        HttpServletRequest request = null;
        for (Object obj : args) {
            if (obj instanceof HttpServletRequest) {
                request = (HttpServletRequest) obj;
                break;
            }
        }
        return request;
    }

    public static HttpServletResponse getResponse(
            ProceedingJoinPoint proceedingJoinPoint) {
        Object[] args = proceedingJoinPoint.getArgs();
        HttpServletResponse response = null;
        for (Object obj : args) {
            if (obj instanceof HttpServletResponse) {
                response = (HttpServletResponse) obj;
                break;
            }
        }
        return response;
    }
}
